package it.amedeo;

import it.amedeo.mybatis.javaclient.AnagraficheMapper;
import it.amedeo.mybatis.javaclient.EffettiMapper;
import it.amedeo.mybatis.javaclient.InfcomuniMapper;
import it.amedeo.mybatis.javaclient.LogelabMapper;
import it.amedeo.mybatis.javaclient.StrcodcomnasMapper;
import it.amedeo.mybatis.javaclient.StrcodcomresMapper;
import it.amedeo.mybatis.javaclient.StrcodfiscMapper;
import it.amedeo.mybatis.javaclient.StrcodiceregioneMapper;
import it.amedeo.mybatis.javaclient.StrcodprvresMapper;
import it.amedeo.mybatis.javaclient.StrdatnasMapper;
import it.amedeo.mybatis.javaclient.ext.StrindirMapperext;
import it.amedeo.mybatis.javaclient.ext.StrnomiMapperext;
import it.amedeo.mybatis.javamodel.Anagrafiche;
import it.amedeo.mybatis.javamodel.Effetti;
import it.amedeo.mybatis.javamodel.Infcomuni;
import it.amedeo.mybatis.javamodel.InfcomuniExample;
import it.amedeo.mybatis.javamodel.Strcodcomnas;
import it.amedeo.mybatis.javamodel.Strcodcomres;
import it.amedeo.mybatis.javamodel.Strcodfisc;
import it.amedeo.mybatis.javamodel.Strcodiceregione;
import it.amedeo.mybatis.javamodel.Strcodprvres;
import it.amedeo.mybatis.javamodel.Strdatnas;
import it.amedeo.utils.CreaLogElab;
import it.amedeo.utils.CreaNomeTabStringhe;
import it.amedeo.utils.FindSQLExceptionWithVendorErrorCode;
import it.amedeo.utils.MyBatisConnectionFactory;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;

public class Am01_Aggioramento {
	private static String alberto = null;
	private static int BUFFER_SIZE = 0;
	private static byte[] bytes = null;
	private static BufferedInputStream in = null;
	private static int n = 0;
	private static SqlSession sqlSession = null;
	private static Anagrafiche anagrafiche = null;
	private static Integer kAnagra = 0;
	private static String sDataIns = null;
	private static Map<String, String> mapPrvReg = null;
	private static Map<String, String> mapInfCodComCodIstat = null;
	private static StrnomiMapperext strnomiMapperext = null;
	private static StrindirMapperext strindirMapperext = null;
	private static InfcomuniMapper infcomuniMapper = null;
	private static StrcodcomnasMapper strcodcomnasMapper = null;
	private static StrcodcomresMapper strcodcomresMapper = null;
	private static StrcodfiscMapper strcodfiscMapper = null;
	private static StrcodiceregioneMapper strcodiceregioneMapper = null;
	private static StrcodprvresMapper strcodprvresMapper = null;
	private static StrdatnasMapper strdatnasMapper = null;
	private static AnagraficheMapper anagraficheMapper = null;
	private static LogelabMapper logelabMapper = null;

	public static void main(String[] args) throws IOException {
		if (args.length<1){
			System.out.println("\nParametri in input mancanti.\nEsecuzione interrotta.");
			System.exit(1);
		}
		
//		ReadFilesInDir feadFilesInDir = new ReadFilesInDir();
//		ArrayList<String> listFiles = feadFilesInDir.ReadFilesInDir("d:/sharew7");
		
		DateFormat dFIns = new SimpleDateFormat("yyyyMMdd HHmmss");		            		
		Date dataIns = new Date();
		sDataIns = dFIns.format(dataIns);
		String riga = "";
		Integer lettiTot=0;
		Integer lettiAnag=0;
		Integer doppiAnag=0;
		Integer scrittiAnag=0;
		Integer lettiEff=0;
		Integer scrittiEff=0;

		MyBatisConnectionFactory.openSqlSessionFactory();
		MyBatisConnectionFactory.openSqlSession();
		sqlSession = MyBatisConnectionFactory.getSqlSession();
		
//		File fileOutPippo = new File("D:/FileInfoCam/DBpippo.txt");
//		fileOutPippo.delete();
//		AnagraficheMapperExt anagraficheMapperExt = null;
//		anagraficheMapperExt = sqlSession.getMapper(AnagraficheMapperExt.class);
//		anagraficheMapperExt.selectPippo();
		
		anagraficheMapper = sqlSession.getMapper(AnagraficheMapper.class);
        logelabMapper = sqlSession.getMapper(LogelabMapper.class);
		strnomiMapperext = sqlSession.getMapper(StrnomiMapperext.class);
		strindirMapperext = sqlSession.getMapper(StrindirMapperext.class);
		strcodcomnasMapper = sqlSession.getMapper(StrcodcomnasMapper.class);
		strcodcomresMapper = sqlSession.getMapper(StrcodcomresMapper.class);
		strcodfiscMapper = sqlSession.getMapper(StrcodfiscMapper.class);
		strcodiceregioneMapper = sqlSession.getMapper(StrcodiceregioneMapper.class);
		strcodprvresMapper = sqlSession.getMapper(StrcodprvresMapper.class);
		strdatnasMapper = sqlSession.getMapper(StrdatnasMapper.class);
		infcomuniMapper = sqlSession.getMapper(InfcomuniMapper.class);

		InfcomuniExample infcomuniExample = new InfcomuniExample();
		infcomuniExample.createCriteria().andCodregioneNotEqualTo("00");
		List<Infcomuni> lstInfComuni =  infcomuniMapper.selectByExample(infcomuniExample);
		mapPrvReg = new HashMap<String, String>();
		mapInfCodComCodIstat = new HashMap<String, String>();
		for (int i = 0; i < lstInfComuni.size(); i++) {
			mapPrvReg.put(lstInfComuni.get(i).getSiglaprovincia().trim(), lstInfComuni.get(i).getCodregione());
			mapInfCodComCodIstat.put(lstInfComuni.get(i).getInfcodicecomune(), lstInfComuni.get(i).getCodistat());
		}
		
    	new CreaLogElab(" ----- INIZIO ELABORAZIONE -----");
    	new CreaLogElab(" ----- INIZIO ELABORAZIONE ANAGRAFICHE -----");

		BUFFER_SIZE = 502;
		bytes = new byte[BUFFER_SIZE];
		in = new BufferedInputStream(new FileInputStream(args[0].toString()));
		riga = "";
		n = in.read(bytes, 0, BUFFER_SIZE);
		while (n >= 0) {
			riga = new String(bytes);
			lettiTot++;
//			if (lettiTot > 91500) {
//				System.out.println("Record n.:" + lettiTot + "-" + riga.trim() + "-");				
//			}

			if (riga != null) {
	            if (riga.substring(9, 11).equals("TS")) {
	            	new CreaLogElab(" File Anagrafiche elaborato:" + riga);
				}
	            anagrafiche = new Anagrafiche();
	            if (riga.substring(9, 11).equals("AN")) {
	            	lettiAnag++;
	            	anagrafiche.setFlgcan("0");
	            	anagrafiche.setKanagra(Integer.parseInt(riga.substring(11, 20)));	            	
	            	anagrafiche.setNominativo(riga.substring(20, 263).trim());
	            	anagrafiche.setCodicefiscale(riga.substring(263, 279).trim());
	            	if (mapPrvReg.containsKey(riga.substring(282, 284).trim())) {
						anagrafiche.setCodregioneres(mapPrvReg.get(riga.substring(282, 284).trim()));
	            	} else {
	            		anagrafiche.setCodregioneres("00");
	            		if (!riga.substring(282, 284).trim().equals("")) {
		                	new CreaLogElab("Recupero codreg - provincia res. sconosciuta. Record: " + riga.trim());	            			
	            		}
	            	}
	            	if (mapInfCodComCodIstat.containsKey(riga.substring(284, 289))) {
	            		String codIstat = mapInfCodComCodIstat.get(riga.substring(284, 289));
	            		String codPrv = codIstat.substring(0,3);
	            		String codCom = codIstat.substring(3, 6);
						anagrafiche.setCodistatprvres(codPrv);
						anagrafiche.setCodistatcomres(codCom);
	            	} else {
						anagrafiche.setCodistatprvres("000");
						anagrafiche.setCodistatcomres("000");
	            		if (!riga.substring(284, 289).trim().equals("")) {
		                	new CreaLogElab("Recupero istatcodprv e istatcodcom  - Infcodcomres sconosciuto. Record: " + riga.trim());	            			
	            		}
	            	}
	            	anagrafiche.setCodicestatoresidenza(riga.substring(279, 282).trim());
	            	anagrafiche.setSiglaprovinciaresidenza(riga.substring(282, 284).trim());	      
	            	anagrafiche.setCodicecomuneresidenza(riga.substring(284, 289).trim());	  
	            	anagrafiche.setIndirizzoresidenza(riga.substring(289, 369).trim());
	            	anagrafiche.setDatanascita(riga.substring(369, 377).trim());
	            	anagrafiche.setCodicestatonascita(riga.substring(377, 380).trim());
	            	if (mapInfCodComCodIstat.containsKey(riga.substring(382, 387))) {
	            		String codIstat = mapInfCodComCodIstat.get(riga.substring(382, 387));
	            		String codPrv = codIstat.substring(0,3);
	            		String codCom = codIstat.substring(3, 6);
						anagrafiche.setCodistatprvnas(codPrv);
						anagrafiche.setCodistatcomnas(codCom);
	            	} else {
						anagrafiche.setCodistatprvnas("000");
						anagrafiche.setCodistatcomnas("000");
	            		if (!riga.substring(382, 387).trim().equals("")) {
		                	new CreaLogElab("Recupero istatcodprv e istatcodcom  - Infcodcomnas sconosciuto. Record: " + riga.trim());	            			
	            		}
	            	}
	            	anagrafiche.setSiglaprovincianascita(riga.substring(380, 382).trim());	            	
	            	anagrafiche.setCodicecomunenascita(riga.substring(382, 387).trim());
	            	anagrafiche.setLuogonascita(riga.substring(387, 467).trim());
	            	anagrafiche.setNumtoteff(0);
	            	anagrafiche.setImptoteff(0.0);
	            	anagrafiche.setDataprimoeff("99999999");
	            	anagrafiche.setDataulteff("00000000");
	            	anagrafiche.setDatatimeins(sDataIns);
	            	try {
		            	anagraficheMapper.insert(anagrafiche);
		            	scrittiAnag++;
		            	creaParole(riga);
		            	if (((scrittiAnag / 10000) * 10000) == scrittiAnag) {
		                	new CreaLogElab("Anagrafiche nuove inserite............: " + scrittiAnag);		                    
		                    sqlSession.commit();
		            	}
					} catch (Exception e) { // chiave duplicata?
						if (FindSQLExceptionWithVendorErrorCode.SqlDuplicateKey(e).equals("error")) {
					    	new CreaLogElab(" ***** FINE ANOMALA : " + e.getMessage());
							e.printStackTrace();
						} else {
//					        anagraficheMapper.updateByPrimaryKey(anagrafiche);
							doppiAnag++;
						}
					}
				}
	        }
        	n = in.read(bytes, 0, BUFFER_SIZE);
		}
		
    	new CreaLogElab(" ----- FINE ELABORAZIONE ANAGRAFICHE -----");
    	new CreaLogElab("Anagrafiche lette.....................: " + lettiAnag);
    	new CreaLogElab("Anagrafiche gia' censite scartate.....: " + doppiAnag);
    	new CreaLogElab("Anagrafiche nuove inserite............: " + scrittiAnag);
        sqlSession.commit();
		
		String giaScaricatiEff = "si";
        EffettiMapper effettiMapper = sqlSession.getMapper(EffettiMapper.class);
        ArrayList<String> lstEff = new ArrayList<String>();
    	new CreaLogElab(" ----- INIZIO ELABORAZIONE EFFETTI -----");

    	BUFFER_SIZE = 202;
		bytes = new byte[BUFFER_SIZE];
		in = new BufferedInputStream(new FileInputStream(args[1].toString()));
		riga = "";
		n = in.read(bytes, 0, BUFFER_SIZE);
    	while (n >= 0) {
			riga = new String(bytes);
			if (riga != null) {
	            if (riga.substring(9, 11).equals("TS")) {
	            	new CreaLogElab(" File Effetti elaborato:" + riga);
				}
	            if (riga.substring(9, 11).equals("EF")) {
	            	if (giaScaricatiEff.equals("si")) {
						lstEff.clear();
						giaScaricatiEff = "no";
					}
	            	lstEff.add(riga);
	            	lettiEff++;
				} else {
					if (riga.substring(9, 11).equals("AC")) {
						kAnagra = Integer.parseInt(riga.substring(11, 20));
						for (Iterator<String> iterator2 = lstEff.iterator(); iterator2.hasNext();) {
							String stringa = (String) iterator2.next();
				            Effetti effetti = new Effetti();
				            effetti.setKanagra(kAnagra);
				            effetti.setCciaapubblicazione(stringa.substring(11, 13).trim());
				            effetti.setDataiscrizione(stringa.substring(13, 21).trim());
				            effetti.setDatalevata(stringa.substring(21, 29).trim());
				            effetti.setSiglaprovincialevata(stringa.substring(29, 31).trim());
				            effetti.setCodicecomunelevata(stringa.substring(31, 36).trim());				            
				            effetti.setDatascadenza(stringa.substring(36, 44).trim());
				            effetti.setTiposcadenza(stringa.substring(44, 45).trim());
				            effetti.setTipoeffetto(stringa.substring(45, 46).trim());
				            effetti.setImporto((Double.parseDouble(stringa.substring(46, 61))) / 1000);
				            effetti.setCodicevaluta(stringa.substring(61, 64).trim());
				            effetti.setImportocorrente((Double.parseDouble(stringa.substring(64, 79))) / 1000);
				            effetti.setCodicevalutacorrente(stringa.substring(79, 82).trim());
				            effetti.setCodmotmancpag(stringa.substring(82, 85).trim());
				            effetti.setStatoeffetto(stringa.substring(85, 86).trim());
				            effetti.setDatatimeins(sDataIns);

				            effettiMapper.insert(effetti);
				            scrittiEff++;
			            	if (((scrittiEff / 10000) * 10000) == scrittiEff) {
			                	new CreaLogElab("Effetti inseriti............: " + scrittiEff);		                    
			                    sqlSession.commit();							
			            	}
			            	anagrafiche = anagraficheMapper.selectByPrimaryKey(kAnagra);
			            	Integer numTotEff = anagrafiche.getNumtoteff();
			            	Double impTotEff = anagrafiche.getImptoteff();
			            	String dataPrimoEff = anagrafiche.getDataprimoeff();
			            	String dataUltEff = anagrafiche.getDataulteff();
			            	anagrafiche = new Anagrafiche();
			            	anagrafiche.setKanagra(kAnagra);
			    			anagrafiche.setNumtoteff(numTotEff + 1);
			    			if (effetti.getCodicevaluta().trim().equals("EU")) {
				    			anagrafiche.setImptoteff(impTotEff + effetti.getImporto());
							} else {
				    			anagrafiche.setImptoteff(impTotEff + effetti.getImportocorrente());
							}
			    			if (effetti.getDataiscrizione().compareTo(dataPrimoEff) < 0) {
								anagrafiche.setDataprimoeff(effetti.getDataiscrizione());
							}
			    			if (effetti.getDataiscrizione().compareTo(dataUltEff) > 0) {
								anagrafiche.setDataulteff(effetti.getDataiscrizione());
							}
			    			anagraficheMapper.updateByPrimaryKeySelective(anagrafiche);
						}
						giaScaricatiEff = "si";
					}
				}
			}
        	n = in.read(bytes, 0, BUFFER_SIZE);
		}
    	new CreaLogElab(" ----- FINE ELABORAZIONE EFFETTI -----");
    	new CreaLogElab("Effetti letti...............: " + lettiEff);
    	new CreaLogElab("Effetti inseriti............: " + scrittiEff);
    	new CreaLogElab(" ----- FINE ELABORAZIONE -----");
        sqlSession.commit();
    	sqlSession.close();
	}
		
		
		
	private static void creaParole (String riga) { 
//		String[] arrNome = null;
//		String[] arrIndir = null;
		
		
		String[] arrNome = riga.substring(20, 263).trim().split(" ");
		// elimino eventuali parole doppie (es. DI MAURO MAURO)
		Map<String, Integer> mapNome = new HashMap<String, Integer>();
		for (int i = 0; i < arrNome.length; i++) {
			if (arrNome[i].trim().length() > 20) {
				arrNome[i] = arrNome[i].trim().substring(0, 20);
			}
			mapNome.put(arrNome[i].trim(), Integer.parseInt(riga.substring(11, 20)));
		}
		for (Map.Entry<String, Integer> entry : mapNome.entrySet()) {
			if (entry.getKey().length() > 1) {
				Map<String, String> param = new HashMap<String, String>();
				CreaNomeTabStringhe creaNomeTabStringhe = new CreaNomeTabStringhe();
				param.put("tableName", creaNomeTabStringhe.CreaNomeTabStringhe("nomi", entry.getKey().length()));
				param.put("kanagra", riga.substring(11, 20));
				param.put("parola", entry.getKey());
				param.put("datatimeins", sDataIns);
				strnomiMapperext.insertTab(param);
			}
		}		


		String[] arrIndir = riga.substring(289, 369).trim().split(" ");
		// elimino eventuali parole doppie (es. VIA GIOVANNI DE GIOVANNI)
		Map<String, Integer> mapIndir = new HashMap<String, Integer>();
		for (int i = 0; i < arrIndir.length; i++) {
			if (arrIndir[i].trim().length() > 20) {
				arrIndir[i] = arrIndir[i].trim().substring(0, 20);
			}
			mapIndir.put(arrIndir[i].trim(), Integer.parseInt(riga.substring(11, 20)));
		}
		for (Map.Entry<String, Integer> entry : mapIndir.entrySet()) {
			if (entry.getKey().length() > 1) {
				Map<String, String> param = new HashMap<String, String>();
				CreaNomeTabStringhe creaNomeTabStringhe = new CreaNomeTabStringhe();
				param.put("tableName", creaNomeTabStringhe.CreaNomeTabStringhe("indir", entry.getKey().length()));
				param.put("kanagra", riga.substring(11, 20));
				param.put("parola", entry.getKey());
				param.put("datatimeins", sDataIns);
				strindirMapperext.insertTab(param);
			}
		}		
		
        if (riga.substring(263, 279).trim().trim().length() > 0) {
        	Strcodfisc strcodfisc = new Strcodfisc();
        	strcodfisc.setParola(riga.substring(263, 279).trim());
        	strcodfisc.setKanagra(Integer.parseInt(riga.substring(11, 20)));
        	strcodfisc.setDatatimeins(sDataIns);
			try {        	
				strcodfiscMapper.insert(strcodfisc);
			} catch (Exception e) {
				if (FindSQLExceptionWithVendorErrorCode.SqlDuplicateKey(e).equals("error")) {
			    	new CreaLogElab(" ***** FINE ANOMALA : " + e.getMessage());					
					e.printStackTrace();					
				} else {
					
				}
			}
		}
        
    	if (riga.substring(369, 377).trim().length() > 0) {
        	Strdatnas strdatnas = new Strdatnas();
    		strdatnas.setParola(riga.substring(369, 377));
    		strdatnas.setKanagra(Integer.parseInt(riga.substring(11, 20)));
    		strdatnas.setDatatimeins(sDataIns);
			try {    		
				strdatnasMapper.insert(strdatnas);
			} catch (Exception e) {
				if (FindSQLExceptionWithVendorErrorCode.SqlDuplicateKey(e).equals("error")) {
			    	new CreaLogElab(" ***** FINE ANOMALA : " + e.getMessage());					
					e.printStackTrace();					
				} else {
					
				}
			}
    	}
    	
    	if (riga.substring(382, 387).trim().length() > 0) {
        	Strcodcomnas strcodcomnas = new Strcodcomnas();
    		strcodcomnas.setParola(riga.substring(382, 387));
    		strcodcomnas.setKanagra(Integer.parseInt(riga.substring(11, 20)));
    		strcodcomnas.setDatatimeins(sDataIns);
			try {    		
				strcodcomnasMapper.insert(strcodcomnas);
			} catch (Exception e) {
				if (FindSQLExceptionWithVendorErrorCode.SqlDuplicateKey(e).equals("error")) {
			    	new CreaLogElab(" ***** FINE ANOMALA : " + e.getMessage());					
					e.printStackTrace();					
				} else {
					
				}
			}
    	}
    	
    	if (riga.substring(284, 289).trim().length() > 0) {
        	Strcodcomres strcodcomres = new Strcodcomres();
    		strcodcomres.setParola(riga.substring(284, 289));
    		strcodcomres.setKanagra(Integer.parseInt(riga.substring(11, 20)));
    		strcodcomres.setDatatimeins(sDataIns);
			try {    		
				strcodcomresMapper.insert(strcodcomres);
			} catch (Exception e) {
				if (FindSQLExceptionWithVendorErrorCode.SqlDuplicateKey(e).equals("error")) {
			    	new CreaLogElab(" ***** FINE ANOMALA : " + e.getMessage());					
					e.printStackTrace();					
				} else {
					
				}
			}
    	}
    	
    	if (riga.substring(282, 284).trim().length() > 0) {
        	Strcodprvres strcodprvres = new Strcodprvres();    		
    		strcodprvres.setParola(riga.substring(282, 284));
    		strcodprvres.setKanagra(Integer.parseInt(riga.substring(11, 20)));
    		strcodprvres.setDatatimeins(sDataIns);
			try {    		
				strcodprvresMapper.insert(strcodprvres);
			} catch (Exception e) {
				if (FindSQLExceptionWithVendorErrorCode.SqlDuplicateKey(e).equals("error")) {
			    	new CreaLogElab(" ***** FINE ANOMALA : " + e.getMessage());					
					e.printStackTrace();					
				} else {
					
				}
			}
			if (mapPrvReg.containsKey(riga.substring(282, 284).trim())) {
	        	Strcodiceregione strcodiceregione = new Strcodiceregione();    		
	        	strcodiceregione.setParola(mapPrvReg.get(riga.substring(282, 284).trim()));
	        	strcodiceregione.setKanagra(Integer.parseInt(riga.substring(11, 20)));
	        	strcodiceregione.setDatatimeins(sDataIns);
				try {    		
					strcodiceregioneMapper.insert(strcodiceregione);
				} catch (Exception e) {
					if (FindSQLExceptionWithVendorErrorCode.SqlDuplicateKey(e).equals("error")) {
				    	new CreaLogElab(" ***** FINE ANOMALA : " + e.getMessage());					
						e.printStackTrace();					
					} else {
						
					}
				}
			} 
    	}
	}
	
	
	
	
	
	
	public static String readDoc(File f) {
	    String text = "";
	    int read, N = 1024 * 1024 * 10;
//	    int read, N = 600000000;
	    char[] buffer = new char[N];

	    try {
	        FileReader fr = new FileReader(f);
	        BufferedReader br = new BufferedReader(fr);

	        while(true) {
	            try {
					read = br.read(buffer, 0, N);
					text += new String(buffer, 0, read);

//					System.out.println(text);
					
					if(read < N) {
					    break;
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
	        }
	    } catch(Exception ex) {
	        ex.printStackTrace();
	    }

	    return text;
	}
}
